<template>
	<view class="root">
		<map
			id="map"
			:longitude="location.longitude"
			:latitude="location.latitude"
			:markers="passengers"
			:show-location="true"
			:enable-traffic="true"
			:enable-3D="true"
			:show-compass="true"
			:include-points="includePoints"
			@callouttap="callouttap"
		/>

		<view class="container-1" v-if="status === 1">
			<view
				v-for="(passenger, index) in passengers"
				:key="index"
				:style="{
					backgroundColor: passenger.list.status
						? '#70A8DB'
						: '#5487e5',
				}"
				class="passenger"
			>
				<label class="info">
					<image class="avatar" :src="passenger.list.avatarUrl" />
					<view class="info-text">
						<text class="nickName ellipsis">
							{{ passenger.list.nickName }}
						</text>
						<text class="routes multi-ellipsis">
							{{ passenger.list.routes }}
						</text>
					</view>
				</label>

				<view class="operation">
					<view
						@click="callPhone(passenger.list.phoneNumber)"
						class="contact"
					>
						<image
							mode="aspectFit"
							class="icon-callPhone"
							src="/static/images/icon-callPhone.png"
						/>
						<text>联系ta</text>
					</view>
					<label class="delimiter" />
					<view @click="toPickUp(passenger.list)" class="pick-up">
						<image
							mode="aspectFit"
							class="icon-position_white"
							src="/static/images/icon-navigation_white.png"
						/>
						<text>去接ta</text>
					</view>
				</view>
			</view>
		</view>

		<view class="container-2" v-if="[2, 4, 6, 7].includes(status)">
			<view class="content">
				<view class="driver-info">
					<label class="info">
						<image
							class="avatar"
							mode="aspectFill"
							:src="driving.avatarUrl"
						/>
						<view class="info-text">
							<text class="title">
								{{ driving.userName }} {{ driving.numberPlate }}
							</text>
							<text class="car-type">{{ driving.carType }}</text>
						</view>
					</label>
					<image
						@click="callPhone(driving.phoneNumber)"
						class="icon-callPhone"
						src="/static/images/icon-callPhone.png"
					/>
				</view>
				<view v-if="status === 2" class="explain">
					<label>
						<text>司机已接单</text>
						<text class="highlight">{{ driving.routes }}</text>
						<text>城际拼车</text>
					</label>
					<text class="word-break-all">
						<text class="highlight">{{ driving.time }}</text>
						<text>将在</text>
						<text class="highlight">{{ driving.place }}</text>
						<text>接驾</text>
					</text>
				</view>
				<view v-if="status === 4" class="explain">
					<label class="oh">
						<text>司机已出发</text>
						<text class="highlight f1">{{ driving.routes }}</text>
						<text>城际拼车</text>
					</label>
					<label>
						<text>正在前往上车地点，</text>
						<text class="highlight">请准备上车</text>
					</label>
				</view>
				<view v-if="status === 6" class="explain">
					<text class="highlight fs-36">已上车，正在前往目的地</text>
				</view>
				<view v-if="status === 7" class="explain">
					<text class="highlight fs-36">
						已到达目的地，本次行程结束
					</text>
				</view>
			</view>

			<button
				@click="handleTravel"
				hover-class="tap-hover"
				class="btn-cancel"
			>
				{{ [6, 7].includes(status) ? "去支付" : "取消行程" }}
			</button>
		</view>
		<view class="container-3" v-if="[3, 5].includes(status)">
			<view class="journey">
				<view class="position">
					<view class="description">
						<label class="location">
							<text>去</text>
							<text class="color-blue">
								{{ journey.location.address }}
							</text>
						</label>
						<label v-if="journey.time" class="time">
							<text>请在</text>
							<text class="color-blue">{{ journey.time }}</text>
							<text>前到达乘客上车地点</text>
						</label>
						<text v-else class="time">请尽快到达乘客上车地点</text>
					</view>

					<view
						@click="navigation"
						hover-class="tap-hover"
						hover-stay-time="100"
						class="navigation"
					>
						<image
							class="icon-navigation"
							src="/static/images/icon-navigation_black.png"
						/>
						<text>导航</text>
					</view>
				</view>
				<view class="stroke">
					<label class="distance">
						<text>全程</text>
						<text class="color-blue">
							{{ journey.mileage }}公里
						</text>
					</label>
					<label class="time">
						<text>预计</text>
						<text class="color-blue">{{ journey.expected }}</text>
					</label>
				</view>

				<text
					v-if="status === 5 && passengerPayList.length"
					@click="switchPopup(1, 'payStatus')"
					class="show-payStatus color-blue"
				>
					查看乘客付款状态
				</text>

				<navigator
					v-if="numberOfOrders"
					class="stroke"
					hover-class="tap-hover"
					open-type="redirect"
					:url="`/pages/orderHall?order_id=${order_id}&show_header=0`"
				>
					<label class="distance">
						<text>有</text>
						<text class="color-blue">{{ numberOfOrders }}</text>
						<text>条相同目地订单，点击前往抢单</text>
					</label>
				</navigator>
			</view>

			<view class="bottom">
				<view v-if="status === 3" class="passenger-travel">
					<view class="color-blue tail-number">
						<text>尾号</text>
						<text>
							{{
								journey.phoneNumber &&
								journey.phoneNumber.substring(7, 11)
							}}
						</text>
					</view>
					<view class="routes oh">
						<label class="startPoint oh">
							<text class="f1 ellipsis">
								{{ journey.startPoint }}
							</text>
						</label>
						<label @click="chooseLocation" class="destination">
							<text class="f1 ellipsis">
								{{
									journey.destination ||
									destination.name ||
									"请选择目的地位置"
								}}
							</text>
						</label>
					</view>
					<image
						@click="callPhone(journey.phoneNumber)"
						class="icon-callPhone_green"
						src="/static/images/icon-callPhone_green.png"
					/>
				</view>
				<button
					@click="arrived"
					hover-class="tap-hover"
					class="arrived"
				>
					{{ status === 3 ? "已接到乘客" : "到达目的地" }}
				</button>
			</view>

			<popup ref="payStatus" v-if="status === 5">
				<view
					v-for="(passenger, index) in passengerPayList"
					:key="index"
					:style="{
						backgroundColor: '#70A8DB',
					}"
					class="passenger"
				>
					<label class="info">
						<image class="avatar" :src="passenger.avatarUrl" />
						<view class="info-text">
							<text class="nickName ellipsis">
								{{ passenger.nickName }}
							</text>
							<text class="routes multi-ellipsis">
								{{ passenger.phoneNumber }}
							</text>
						</view>

						<text class="status">
							{{ ["未", "已"][Number(passenger.payStatus)] }}付款
						</text>
					</label>
				</view>
			</popup>
		</view>
	</view>
</template>

<script lang="ts">
	import Vue from "vue";
	import Component from "vue-class-component";
	import { UserInfo, Passengers, Driving, Journey } from "@/common/api.d";
	import { Storage, transformQueryString } from "@/libs/utils";
	import popup from "@/components/popup.vue";

	/**
	 * 1.司机依次接送乘客
	 *
	 * 2.乘客等候预约时间
	 *
	 * 3.司机到达上车点
	 *
	 * 4.乘客准备上车
	 *
	 * 5.司机接到乘客
	 *
	 * 6.司机端到达目的地（等待支付）
	 *
	 * 7.乘客端到达目的（等待支付）
	 **/

	let [flag, timers]: [boolean, number[]] = [false, []];
	@Component({ components: { popup } })
	export default class Travel extends Vue {
		userInfo: UserInfo = Storage.get("userInfo");
		status: number = 0;
		order_id: number = 0;
		jiaoche_id: number = 0;
		numberOfOrders: number = 0;

		location: { longitude: number; latitude: number } = {
			longitude: 104.065901,
			latitude: 30.657372,
		};
		passengers: Passengers = [];
		passengerPayList: AnyObject[] = [];
		driving: Driving = {
			userName: "--",
			numberPlate: "--",
			carType: "--",
			routes: "--",
			time: "--",
			phoneNumber: "--",
			place: "--",
		};

		journey: Journey = {
			time: "--",
			location: {
				longitude: 104.065901,
				latitude: 30.657372,
				address: "--",
			},
			mileage: "--",
			expected: "--",
			startPoint: "--",
			destination: "--",
			phoneNumber: "--",
		};

		destination: AnyObject = {};

		public get includePoints(): AnyObject[] {
			return this.passengers
				.map(({ longitude, latitude }: AnyObject) => ({
					longitude,
					latitude,
				}))
				.concat(this.location);
		}

		private onLoad({ status, order_id, jiaoche_id }: any): void {
			this.order_id = +order_id;
			this.status = +status;

			+jiaoche_id && (this.jiaoche_id = +jiaoche_id);

			uni.getLocation({
				success: ({ longitude, latitude }) => {
					this.location = { longitude, latitude };

					this.request
						.get("/api/maps", {
							type: (this.userInfo.identity as any) + 1,
							orderid: order_id,
							jiaoche_id: jiaoche_id || "",
							longitude,
							latitude,
						})
						.then(({ data }) => {
							data.passengers && (this.passengers = data.passengers);
							data.passengerPayList &&
								(this.passengerPayList = data.passengerPayList);
							data.driving && (this.driving = data.driving);
							data.journey && (this.journey = data.journey);
						});
				},
				fail: () =>
					uni.showToast({
						title: "获取位置失败",
						duration: 2000,
						icon: "none",
					}),
			});

			this.status === 5 && this.checkHasNewOrder();
		}

		private onShow(): void {
			(this.userInfo.identity ? [5] : [2, 4]).includes(+this.status) &&
				((flag = false), this.getOrderStatus());
		}

		private onUnload(): void {
			this.clearTimer();
		}
		private onHide(): void {
			this.clearTimer();
		}

		public switchPopup(onOff: 0 | 1, refName: string): void {
			(this.$refs as AnyObject)[refName][onOff ? "open" : "close"]();
		}

		public callouttap({ markerId }: AnyObject): void {
			uni.showActionSheet({
				itemList: ["去接Ta", "联系Ta"],
				success: ({ tapIndex }) => {
					const { list } = this.passengers[markerId];
					tapIndex
						? uni.makePhoneCall({ phoneNumber: list.phoneNumber })
						: this.toPickUp(list);
				},
			});
		}

		public getOrderStatus(): void {
			const { status, request, getOrderStatus } = this;

			request.get("/api/checkOrder").then(({ data }) => {
				if (flag) return;
				const statusPages: AnyObject = {
					"1": {
						status: 2,
						jiaoche_id: data.jiaoche_id,
					},
					"2": {
						status: 4,
						jiaoche_id: data.jiaoche_id,
					},
					"3": {
						status: 6,
					},
					"4": {
						status: 7,
					},
					"5": {
						status: 1,
					},
					"6": {
						status: 3,
					},
					"7": {
						status: 5,
					},
				};

				if (statusPages[data.status.toString()].status === status) {
					timers.push(setTimeout(getOrderStatus, 5000));
					return;
				}

				data.status &&
					uni.redirectTo({
						url: `/pages/travel?${transformQueryString(
							Object.assign(statusPages[data.status.toString()], {
								order_id: data.order_id,
							})
						)}`,
					});
			});
		}

		public clearTimer(): void {
			flag = true;
			timers.forEach((timer) => clearTimeout(timer));
		}

		public handleTravel(): void {
			// 支付
			if ([6, 7].includes(this.status)) {
				uni.showActionSheet({
					itemList: ["余额支付", "微信支付"],
					success: ({ tapIndex }) => {
						if (tapIndex === 0) {
							this.request
								.get(`/api/moneyPay?order_id=${this.order_id}`)
								.then((res) =>
									uni.redirectTo({
										url: `/pages/orderInfo?order_id=${this.order_id}`,
									})
								)
								.catch(({ msg: title }) =>
									uni.showToast({
										title,
										icon: "none",
									})
								);
							return;
						}

						if (tapIndex === 1) {
							this.request
								.get(`/api/pay?order_id=${this.order_id}`)
								.then(({ data }) => {
									uni.requestPayment({
										provider: "wxpay",
										...data,
										success: () =>
											uni.redirectTo({
												url: `/pages/orderInfo?order_id=${this.order_id}`,
											}),
										fail: (res) => {
											uni.showToast({
												title: "支付失败",
												icon: "none",
											});
										},
									});
								});
						}
					},
				});
				return;
			}
			// 取消行程
			this.request.get(`/api/cancelOrder?id=${this.order_id}`).then((res) =>
				uni.showToast({
					title: "本次行程已取消",
					success: () => setTimeout(uni.navigateBack, 1200),
				})
			);
		}

		public navigation(): void {
			uni.openLocation({ ...this.journey.location });
		}

		public toPickUp({ jiaoche_id, status }: AnyObject): void {
			if (+status) return;
			this.request
				.get(`/api/chucheDeal`, {
					id: this.order_id,
					jiaoche_id,
					status: 2,
				})
				.then((res) =>
					uni.redirectTo({
						url: `/pages/travel?status=3&order_id=${this.order_id}&jiaoche_id=${jiaoche_id}`,
					})
				)
				.catch((res) => res);
		}

		public arrived(): void {
			if (this.status === 3) {

				for(let key in this.destination){
					this.destination["end_" + key] = this.destination[key];
					delete this.destination[key];
				}

				this.request
					.get("/api/chucheDeal", {
						id: this.order_id,
						status: 3,
						jiaoche_id: this.jiaoche_id,
						...this.destination
					})
					.then(({ data }) => {
						uni.redirectTo({
							url: `/pages/travel?status=${
								+data.status === 1 ? 1 : 5
							}&order_id=${this.order_id}`,
						});
					});
				return;
			}

			this.request
				.get(`/api/chucheDeal?id=${this.order_id}&status=4`)
				.then(() => uni.redirectTo({ url: "/pages/order" }));
		}

		public callPhone(phoneNumber: string): void {
			uni.makePhoneCall({ phoneNumber });
		}

		public checkHasNewOrder(): void {
			this.request
				.get(`/api/sijiWaitPinV2?id=${this.order_id}`)
				.then(({ data }: any) => {
					if (flag) return;
					this.numberOfOrders = data.recommends.length;

					timers.push(setTimeout(this.checkHasNewOrder, 5000));
				});
		}

		public async chooseLocation(): Promise<void> {
			if (this.journey.destination) return;

			const [fail, locationResult]: any = await uni.chooseLocation({});

			if (fail) return;
			this.destination = locationResult;
		}
	}
</script>

<style>
	page {
		height: 100%;
	}
</style>

<style lang="scss" scoped>
	.root {
		height: 100%;
		position: relative;
		color: #1b1b1b;
		map {
			width: 100%;
			height: 100%;
		}

		.icon-callPhone,
		.icon-callPhone_green,
		.icon-position_white {
			width: 66rpx;
			height: 66rpx;
		}

		.icon-navigation {
			width: 45rpx;
			height: 45rpx;
		}

		.avatar {
			width: 100rpx;
			height: 100rpx;
			border-radius: 50%;
			margin-right: 18rpx;
		}

		.color-blue {
			color: #5487e5;
		}

		.fs-36 {
			font-size: 36rpx;
		}

		.container-1 {
			position: absolute;
			top: 30rpx;
			left: 30rpx;
			right: 30rpx;
			.passenger {
				flex-direction: row;
				align-items: center;
				padding: 30rpx;
				color: #fff;
				border-radius: 10rpx;
				margin-bottom: 10rpx;
				.info {
					flex: 1;
					overflow: hidden;
					.info-text {
						flex: 1;
						overflow: hidden;
						.nickName {
							font-size: 36rpx;
						}
						.routes {
							font-size: 24rpx;
						}
					}
				}
				.operation {
					flex-direction: row;
					align-items: center;
					.delimiter {
						height: 45rpx;
						width: 3rpx;
						background-color: rgba(255, 255, 255, 0.3);
						margin: 0 25rpx;
					}
					.contact,
					.pick-up {
						font-size: 30rpx;
						align-items: center;
						text {
							margin-top: 20rpx;
						}
					}
				}
			}
		}

		.container-2 {
			.content {
				position: absolute;
				top: 30rpx;
				left: 30rpx;
				right: 30rpx;
				padding: 20rpx 30rpx;
				background-color: #5487e5;
				border-radius: 10rpx;
				.driver-info {
					flex-direction: row;
					.info {
						flex: 1;
					}
					.info-text {
						color: #fff;
						.title {
							font-size: 36rpx;
						}
						.car-type {
							font-size: 24rpx;
						}
					}
				}
				.explain {
					margin-top: 30rpx;
					font-size: 24rpx;
					line-height: 1.5;
					color: #fff;
					.f1 {
						flex: 1;
					}
					.highlight {
						color: #ffff00;
						margin: 0 0.6em;
					}
				}
			}
			.btn-cancel {
				position: absolute;
				background-color: #5487e5;
				color: #fff;
				bottom: 70rpx;
				left: 20rpx;
				right: 20rpx;
			}
		}

		.container-3 {
			.journey {
				position: absolute;
				top: 30rpx;
				left: 30rpx;
				right: 30rpx;
				background-color: #fff;
				box-shadow: 0 0 8rpx #ddd;
				border-radius: 20rpx;
				.position {
					padding: 30rpx;
					flex-direction: row;
					align-items: center;
					.description {
						flex: 1;
						.location {
							font-size: 30rpx;
							.color-blue {
								margin-left: 12rpx;
							}
						}
						.time {
							font-size: 24rpx;
						}
					}
					.navigation {
						align-items: center;
						font-size: 30rpx;
						margin-right: 50rpx;
					}
				}
				.stroke {
					flex-direction: row;
					align-items: center;
					line-height: 80rpx;
					margin: 0 30rpx;
					font-size: 30rpx;
					border-top: solid 1rpx #eee;
					.distance,
					.time {
						flex: 1;
						justify-content: center;
					}
				}

				.show-payStatus {
					margin: 0 30rpx;
					line-height: 2;
					text-align: center;
					font-size: 30rpx;
					text-decoration: underline;
				}
			}

			.passenger {
				flex-direction: row;
				align-items: center;
				padding: 10rpx 30rpx;
				color: #fff;
				border-radius: 10rpx;
				margin-bottom: 10rpx;
				.info {
					flex: 1;
					overflow: hidden;
					.info-text {
						flex: 1;
						overflow: hidden;
						.nickName {
							font-size: 36rpx;
						}
						.routes {
							font-size: 24rpx;
						}
					}
				}
				.status {
					margin-left: 50rpx;
					font-size: 30rpx;
				}
			}
			.bottom {
				position: absolute;
				bottom: 50rpx;
				left: 20rpx;
				right: 20rpx;
				.passenger-travel {
					flex-direction: row;
					align-items: center;
					background-color: #fff;
					border-radius: 20rpx;
					.tail-number {
						align-items: center;
						font-size: 32rpx;
						margin: 30rpx 45rpx;
					}
					.routes {
						flex: 1;
						padding: 0 30rpx;
						font-size: 28rpx;
						border-left: 1rpx solid #eee;
						.startPoint::before {
							background-color: #17ad82;
						}
						.destination::before {
							background-color: #5487e5;
						}
						.startPoint,
						.destination {
							padding: 12rpx 0;
							&::before {
								content: "";
								width: 14rpx;
								height: 14rpx;
								border-radius: 50%;
								margin-right: 18rpx;
							}
							text {
								flex: 1;
							}
						}
					}
					.icon-callPhone_green {
						margin: 0 30rpx;
					}
				}
				.arrived {
					margin-top: 20rpx;
					line-height: 150rpx;
					background-color: #5487e5;
					color: #fff;
					width: 100%;
					border-radius: 20rpx;
				}
			}
		}
	}
</style>